<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>URL 编解码工具 (左右结构)</title>
    <style>
        * {
            box-sizing: border-box;
        }
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
            padding: 20px;
        }
        .container {
            background-color: white;
            padding: 2rem;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            width: 95%;
            max-width: 1000px;
            display: flex;
            flex-direction: column;
        }
        h1 {
            text-align: center;
            margin-top: 0;
            color: #333;
            margin-bottom: 1.5rem;
        }
        .main-content {
            display: flex;
            gap: 2rem;
            flex: 1;
        }
        @media (max-width: 768px) {
            .main-content {
                flex-direction: column;
            }
        }
        .panel {
            flex: 1;
            display: flex;
            flex-direction: column;
        }
        .panel h2 {
            margin-top: 0;
            color: #444;
            text-align: center;
            padding-bottom: 0.5rem;
            border-bottom: 1px solid #eee;
        }
        .input-group, .output-group {
            display: flex;
            flex-direction: column;
            flex: 1;
            min-height: 0; /* 允许内部滚动 */
        }
        label {
            display: block;
            margin-bottom: 0.5rem;
            font-weight: bold;
            color: #555;
        }
        textarea, .result {
            flex: 300px;
            width: 100%;
            padding: 0.75rem;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
            font-family: monospace;
            resize: none; /* 禁用右下角拖拽调整大小 */
            margin-bottom: 1rem;
        }
        textarea:focus, .result:focus {
             outline: none;
             border-color: #007bff;
             box-shadow: 0 0 0 2px rgba(0,123,255,.25);
        }
        .result {
            background-color: #f8f9fa;
            overflow: auto;
            white-space: pre-wrap;
            word-break: break-all;
        }
        .button-group {
            display: flex;
            gap: 10px;
            flex-wrap: wrap;
        }
        button {
            padding: 0.6rem 1rem;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            flex: 1;
            min-width: 80px;
            font-size: 0.9rem;
        }
        button:hover {
            background-color: #0056b3;
        }
        .panel.encode .button-group button.primary { background-color: #28a745; }
        .panel.encode .button-group button.primary:hover { background-color: #1e7e34; }
        
        .panel.decode .button-group button.primary { background-color: #ffc107; color: black; }
        .panel.decode .button-group button.primary:hover { background-color: #e0a800; }
        
        .button-group button.copy-btn {
            background-color: #6c757d;
        }
        .button-group button.copy-btn:hover {
            background-color: #5a6268;
        }
        .error {
            color: #dc3545;
            font-size: 0.85rem;
            margin-top: 0.25rem;
            min-height: 1.2rem;
        }
        .hint {
            font-size: 0.8rem;
            color: #666;
            margin-top: 0.25rem;
            text-align: center;
        }
    </style>
</head>
<body>

<div class="container">
    <h1>URL 编解码工具</h1>
    <div class="main-content">
        <!-- 编码面板 -->
        <div class="panel encode">
            <h2>编码 (Encode)</h2>
            <div class="input-group">
                <label for="encodeInput">原文本:</label>
                <textarea  id="encodeInput" placeholder="输入需要编码的文本..."># 井号测试
param1=value with spaces
param2=特殊字符!@#$%^&*()
url=https://example.com/path?query=search term</textarea>
                <div class="button-group">
                    <button id="encodeComponentBtn" class="primary">encodeURIComponent</button>
                    <button id="encodeURIBtn">encodeURI</button>
                    <button id="copyEncodedBtn" class="copy-btn">复制</button>
                </div>
                <div class="error" id="encodeError"></div>
            </div>
            <div class="output-group">
                <label for="encodeResult">编码结果:</label>
                <div id="encodeResult" class="result" readonly></div>
            </div>
            <div class="hint">使用 encodeURIComponent 编码 URL 参数值，使用 encodeURI 编码整个 URL。</div>
        </div>

        <!-- 解码面板 -->
        <div class="panel decode">
            <h2>解码 (Decode)</h2>
            <div class="input-group">
                <label for="decodeInput">编码文本:</label>
                <textarea id="decodeInput" placeholder="输入需要解码的文本...">#%20%E4%BA%95%E5%8F%B7%E6%B5%8B%E8%AF%95
param1=value%20with%20spaces
param2=%E7%89%B9%E6%AE%8A%E5%AD%97%E7%AC%A6!%40%23%24%25%5E%26*()
url=https%3A%2F%2Fexample.com%2Fpath%3Fquery%3Dsearch%20term</textarea>
                <div class="button-group">
                    <button id="decodeComponentBtn" class="primary">decodeURIComponent</button>
                    <button id="decodeURIBtn">decodeURI</button>
                    <button id="copyDecodedBtn" class="copy-btn">复制</button>
                </div>
                <div class="error" id="decodeError"></div>
            </div>
            <div class="output-group">
                <label for="decodeResult">解码结果:</label>
                <div id="decodeResult" class="result" readonly></div>
            </div>
            <div class="hint">使用 decodeURIComponent 解码 encodeURIComponent 的结果，使用 decodeURI 解码 encodeURI 的结果。</div>
        </div>
    </div>
</div>

<script>
    // DOM 元素 - 编码部分
    const encodeInput = document.getElementById('encodeInput');
    const encodeComponentBtn = document.getElementById('encodeComponentBtn');
    const encodeURIBtn = document.getElementById('encodeURIBtn');
    const copyEncodedBtn = document.getElementById('copyEncodedBtn');
    const encodeResult = document.getElementById('encodeResult');
    const encodeError = document.getElementById('encodeError');

    // DOM 元素 - 解码部分
    const decodeInput = document.getElementById('decodeInput');
    const decodeComponentBtn = document.getElementById('decodeComponentBtn');
    const decodeURIBtn = document.getElementById('decodeURIBtn');
    const copyDecodedBtn = document.getElementById('copyDecodedBtn');
    const decodeResult = document.getElementById('decodeResult');
    const decodeError = document.getElementById('decodeError');

    // 通用编码函数
    function performEncode(inputElement, resultElement, errorElement, useEncodeURI = false) {
        const input = inputElement.value;
        errorElement.textContent = '';
        resultElement.textContent = '';

        if (!input) {
            errorElement.textContent = '请输入文本';
            return;
        }

        try {
            let encoded;
            if (useEncodeURI) {
                encoded = encodeURI(input);
            } else {
                encoded = encodeURIComponent(input);
            }
            resultElement.textContent = encoded;
        } catch (e) {
            errorElement.textContent = '编码失败: ' + (e.message || '未知错误');
        }
    }

    // 通用解码函数
    function performDecode(inputElement, resultElement, errorElement, useDecodeURI = false) {
        const input = inputElement.value;
        errorElement.textContent = '';
        resultElement.textContent = '';

        if (!input) {
            errorElement.textContent = '请输入文本';
            return;
        }

        try {
            let decoded;
            if (useDecodeURI) {
                decoded = decodeURI(input);
            } else {
                decoded = decodeURIComponent(input);
            }
            resultElement.textContent = decoded;
        } catch (e) {
            errorElement.textContent = '解码失败: 输入可能包含无效的编码序列';
        }
    }

    // 复制到剪贴板
    async function copyToClipboard(sourceElement, button) {
        const text = sourceElement.textContent || sourceElement.innerText;
        if (!text) return;
        try {
            await navigator.clipboard.writeText(text);
            const originalText = button.textContent;
            button.textContent = '✓ 已复制';
            setTimeout(() => { button.textContent = originalText; }, 2000);
        } catch (err) {
            console.error('复制失败: ', err);
            // 这里可以添加更友好的用户提示
        }
    }

    // 事件监听 - 编码
    encodeComponentBtn.addEventListener('click', () => performEncode(encodeInput, encodeResult, encodeError, false));
    encodeURIBtn.addEventListener('click', () => performEncode(encodeInput, encodeResult, encodeError, true));
    copyEncodedBtn.addEventListener('click', () => copyToClipboard(encodeResult, copyEncodedBtn));

    // 事件监听 - 解码
    decodeComponentBtn.addEventListener('click', () => performDecode(decodeInput, decodeResult, decodeError, false));
    decodeURIBtn.addEventListener('click', () => performDecode(decodeInput, decodeResult, decodeError, true));
    copyDecodedBtn.addEventListener('click', () => copyToClipboard(decodeResult, copyDecodedBtn));

    // 初始化示例
    window.addEventListener('load', () => {
         performEncode(encodeInput, encodeResult, encodeError, false);
         performDecode(decodeInput, decodeResult, decodeError, false);
    });

</script>

</body>
</html>
